package com.chensi.admin.web.service.impl;

import com.chensi.admin.web.common.Constants;
import com.chensi.admin.web.domain.WebRole;
import com.chensi.admin.web.dto.mapper.WebRoleMapper;
import com.chensi.admin.web.exception.BaseException;
import com.chensi.admin.web.exception.ItemRepeatException;
import com.chensi.admin.web.service.WebRoleService;
import com.chensi.admin.web.util.PageUtil;
import com.google.common.collect.Lists;
import com.chensi.admin.web.dao.WebRoleRepository;
import com.chensi.admin.web.dto.WebRoleDTO;
import com.chensi.admin.web.exception.ItemNotFoundException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @date 2019/6/20 14:08
 */

@Service
public class WebRoleServiceImpl implements WebRoleService {

    private final WebRoleRepository webRoleRepository;

    private final WebRoleMapper webRoleMapper;

    @Autowired
    public WebRoleServiceImpl(WebRoleRepository webRoleRepository, WebRoleMapper webRoleMapper) {
        this.webRoleRepository = webRoleRepository;
        this.webRoleMapper = webRoleMapper;
    }

    @Override
    public List<WebRoleDTO> list() {
        return webRoleRepository.findAll((root, query, cb) -> {
                    Predicate predicate = cb.equal(root.get("deleted"), Constants.DELETED_NO);
                    List<Predicate> predicates = Lists.newArrayList(predicate);
                    query.where(predicates.toArray(new Predicate[0]));
                    return query.getRestriction();
                }
        ).stream().map(webRoleMapper::toDTO).collect(Collectors.toList());
    }

    @Override
    public WebRoleDTO get(String id) throws BaseException {
        return webRoleMapper.toDTO(webRoleRepository.findById(id)
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("WebRole [%s] not found", id))));
    }

    @Override
    public Page<WebRoleDTO> page(String name, Integer pageNum, Integer pageSize) {
        pageNum = PageUtil.pageNum(pageNum);
        pageSize = PageUtil.pageSize(pageSize);
        return webRoleRepository.findAll((root, query, cb) -> {
            Predicate p1 = cb.equal(root.get("deleted"), Constants.DELETED_NO);
            List<Predicate> predicates = Lists.newArrayList(p1);
            if (StringUtils.isNotBlank(name)) {
                predicates.add(cb.like(root.get("name"), "%" + name.trim() + "%"));
            }
            query.where(predicates.toArray(new Predicate[0]));
            return query.getRestriction();
        }, PageRequest.of(pageNum, pageSize))
                .map(webRoleMapper::toDTO);
    }

    @Override
    public WebRoleDTO create(WebRole webRole) throws BaseException {
        Optional<WebRole> webRoleOptional = webRoleRepository.findByNameAndDeleted(webRole.getName(),
                Constants.DELETED_NO);
        if (webRoleOptional.isPresent()) {
            throw new ItemRepeatException(String.format("WebRole: %s is exist", webRole.getName()));
        }
        webRoleRepository.save(webRole);
        return webRoleMapper.toDTO(webRole);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(WebRole webRole) throws BaseException {
        WebRole old = webRoleRepository.findById(webRole.getId())
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("WebRole [%s] not found",
                        webRole.getId())));
        if (old.getName().equals(webRole.getName())) {
            throw new ItemNotFoundException(String.format("WebMenu [%s] is Exist",
                    webRole.getName()));
        }
        webRoleMapper.update(old, webRole);
        webRoleRepository.save(old);
    }

    @Override
    public void delete(String id) throws BaseException {
        //超级管理员不能删除
        //TODO功能完善后refactor
        if ("4028df816baccf6a016bacdf87ac0000".equals(id)) {
            throw new ItemNotFoundException(String.format("WebRole [%s] can not delete", id));
        }
        //前置判断该角色在中间表中是否被引用，如引用则删除中间表中角色的该菜单*/
        String roleId = webRoleRepository.queryRoleId(id);
        if (StringUtils.isNotBlank(roleId)) {
            webRoleRepository.delRoleId(roleId);
        }
        WebRole webRole = webRoleRepository.findById(id)
                .filter(u -> Constants.DELETED_NO == u.getDeleted())
                .orElseThrow(() -> new ItemNotFoundException(String.format("WebRole [%s] not found", id)));
        webRole.setDeleted(Constants.DELETED_YES);
        webRoleRepository.save(webRole);
    }
}
